/**
 * huize Service Inc
 * All Rights Reserved @2018
 */
package com.huize.ladon.apm.common.util;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 描述: 时间工具类
 *
 * @author tianyuliang
 * @version $Id: DateDateTimeUtils.java, v0.1 2019/3/20
 */
public class DateTimeUtils {

    public static final Logger logger = LoggerFactory.getLogger(DateTimeUtils.class);


    /**
     * 每天0点
     */
    public static final int ONE_DAY_ZERO_HOUR = 0;

    /**
     * 每天23点
     */
    public static final int ONE_DAY_MAX_HOUR = 23;

    /**
     * 每天最小时间
     */
    public static final String ZERO_HOUR_MINUTE_SECOND = "00:00:00";

    /**
     * 每天最大时间
     */
    public static final String MAX_HOUR_MINUTE_SECOND = "23:59:59";

    /**
     * 每分钟的毫秒
     */
    public static final Long ONE_MINUTE_DURATION = 60 * 1000L;

    /**
     * 每天的毫秒数
     */
    public static final Long ONE_DAY_SECOND = 1000 * 60 * 60 * 24L;

    /**
     * 标准year格式
     */
    public final static String PATTERN_YEAR = "yyyy";

    /**
     * 标准month格式
     */
    public final static String PATTERN_MONTH = "yyyy.MM";

    /**
     * 标准date格式
     */
    public final static String PATTERN_DATE = "yyyy-MM-dd";

    /**
     * 标准date格式
     */
    public final static String PATTERN_POINT_DATE = "yyyy.MM.dd";

    /**
     * 标准time格式
     */
    public final static String PATTERN_TIME = "yyyy-MM-dd HH:mm:ss";

    /**
     * 拓展time格式
     */
    public final static String PATTERN_EXT_TIME = "HH:mm:ss";

    /**
     * 标准time格式
     */
    public final static String PATTERN_CUSTOM_TIME = "yyyy-MM-dd HH:mm:ss.SSS";

    /**
     * UTC标准时间格式
     */
    public static final String DATE_TIME_TONE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";

    /**
     * 标准time格式 yyyy-MM-dd HH:mm:ss.SSS
     */
    public static ThreadLocal<SimpleDateFormat> customTimeLocal = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat(PATTERN_CUSTOM_TIME);
        }
    };

    /**
     * 拓展time格式 HH:mm:ss
     */
    public static ThreadLocal<SimpleDateFormat> extTimeLocal = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat(PATTERN_EXT_TIME);
        }
    };

    /**
     * 标准time格式 yyyy-MM-dd HH:mm:ss
     */
    public static ThreadLocal<SimpleDateFormat> timeLocal = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat(PATTERN_TIME);
        }
    };

    /**
     * date格式 yyyy-MM-dd
     */
    public static ThreadLocal<SimpleDateFormat> dateLocal = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat(PATTERN_DATE);
        }
    };

    /**
     * date格式 yyyy.MM.dd
     */
    public static ThreadLocal<SimpleDateFormat> datePointLocal = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat(PATTERN_POINT_DATE);
        }
    };

    /**
     * date格式 yyyy.MM
     */
    public static ThreadLocal<SimpleDateFormat> monthPointLocal = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat(PATTERN_MONTH);
        }
    };

    /**
     * 判断字符串(yyyy-MM-dd HH:mm:ss.SSS)能否转化为Date
     *
     * @param object
     * @return
     */
    public static boolean canFormatDateTime(Object object) {
        if (object instanceof Date) {
            String value = formatCustomTime((Date) object);
            return MixAllUtils.isNotEmpty(value);
        }
        return false;
    }

    /**
     * 判断字符串(yyyy-MM-dd)能否转化为Date
     *
     * @param strTime
     * @return
     */
    public static boolean canParseDate(String strTime) {
        try {
            Date date = dateLocal.get().parse(strTime);
            return date != null;
        } catch (ParseException e) {
            return false;
        }
    }

    /**
     * 判断字符串(yyyy-MM-dd HH:mm:ss)能否转化为Date
     *
     * @param strTime
     * @return
     */
    public static boolean canParseTime(String strTime) {
        try {
            timeLocal.get().parse(strTime);
            return true;
        } catch (ParseException e) {
            return false;
        }
    }

    /**
     * 判断字符串(yyyy-MM-dd HH:mm:ss.SSS)能否转化为Date
     *
     * @param strTime
     * @return
     */
    public static boolean canParseMilliTime(String strTime) {
        try {
            SimpleDateFormat timeFormat = customTimeLocal.get();
            timeFormat.parse(strTime);
            return true;
        } catch (ParseException e) {
            return false;
        }
    }

    /**
     * 将字符串(yyyy-MM-dd HH:mm:ss.SSS)转化为Date
     *
     * @param strTime
     * @return
     */
    public static Date parseMilliTime(String strTime) {
        try {
            SimpleDateFormat timeFormat = customTimeLocal.get();
            Date date = timeFormat.parse(strTime);
            return date;
        } catch (ParseException e) {
            logger.error("parse milli time failed, param is not the {} formatter.", strTime);
            return null;
        }
    }

    /**
     * 将毫秒时间戳转化为Date
     *
     * @param timestamp
     * @return
     */
    public static Date parseMilliTime(Long timestamp) {
        if (timestamp == null) {
            return null;
        }

        String value = timestamp.toString();
        if (value.length() < 10 || value.length() > 13) {
            return null;
        }
        if (value.length() == 10) {
            timestamp = timestamp * 1000;
        }

        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(timestamp);
            Date date = calendar.getTime();
            return date;
        } catch (Exception e) {
            logger.error("parseMilliTime error. timestamp={}", timestamp);
            return null;
        }
    }

    /**
     * 将字符串转化为Date，转化过程优先适配"yyyy-MM-dd HH:mm:ss"， 失败后再次适配"yyyy-MM-dd"
     *
     * @param strTime
     * @return
     */
    public static Date parseDateTime(String strTime) {
        Date date = parseTime(strTime);
        if (date == null) {
            date = parseDate(strTime);
        }
        return date;
    }

    /**
     * 将字符串转化为Date，转化过程优先适配"yyyy-MM-dd"， 失败后再次适配"yyyy-MM-dd HH:mm:ss"
     *
     * @param strDate
     * @return
     */
    public static Date parseDefaultDate(String strDate) {
        Date date = parseDate(strDate);
        if (date == null) {
            date = parseTime(strDate);
        }
        return date;
    }

    /**
     * 时区字符串(yyyy-MM-dd'T'HH:mm:ss.SSS'Z')转化为标准日期
     *
     * @param strZoneDate
     * @return
     */
    public static Date parseZoneDate(String strZoneDate) {
        try {
            SimpleDateFormat df = new SimpleDateFormat(DATE_TIME_TONE_FORMAT);
            df.setTimeZone(TimeZone.getTimeZone("UTC"));
            return df.parse(strZoneDate);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 标准日期字符串(yyyy-MM-dd HH:mm:ss)转化为时区字符串(yyyy-MM-dd'T'HH:mm:ss.SSS'Z')
     *
     * @param strDate
     * @return
     */
    public static String convertZoneDate(String strDate) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_TIME_TONE_FORMAT);
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        return simpleDateFormat.format(parseFullDate(strDate));
    }

    /**
     * 将带时区的时间转化为标准格式(yyyy-MM-dd HH:mm:ss)
     *
     * @param strZoneDate
     * @return
     */
    public static String formatZoneDate(String strZoneDate) {
        return formatCustomDate(parseZoneDate(strZoneDate), PATTERN_TIME);
    }

    /**
     * 根据规则格式化日期
     *
     * @param date
     * @param format
     * @return
     */
    public static String formatCustomDate(Date date, String format) {
        if (null == date) {
            return null;
        }
        try {
            return new SimpleDateFormat(format).format(date);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 将待时区的时间转化为标准格式(yyyy-MM-dd HH:mm:ss)
     *
     * @param zoneDate
     * @return
     */
    public static String formatZoneDate(Date zoneDate) {
        return formatCustomDate(zoneDate, PATTERN_TIME);
    }

    /**
     * 字符串(yyyy-MM-dd HH:mm:ss)转化为日期
     *
     * @param strDate
     * @return
     */
    public static Date parseFullDate(String strDate) {
        return parseCustomDate(strDate, PATTERN_TIME);
    }

    /**
     * 将字符串(yyyy-MM-dd HH:mm:ss)转化为Date日期
     *
     * @param strDate
     * @return
     */
    public static Date parseTime(String strDate) {
        Date date = null;
        try {
            SimpleDateFormat timeFormat = timeLocal.get();
            date = timeFormat.parse(strDate);
        } catch (Exception e) {
            return null;
        }
        return date;
    }

    /**
     * 将字符串(yyyy-MM-dd)转化为Date日期
     *
     * @param strDate
     * @return
     */
    public static Date parseDate(String strDate) {
        Date date = null;
        try {
            SimpleDateFormat dateFormat = dateLocal.get();
            date = dateFormat.parse(strDate);
        } catch (Exception e) {
            return null;
        }
        return date;
    }

    /**
     * 自定义字符串格式转化为日期
     *
     * @param strDate
     * @param pattern
     * @return
     */
    public static Date parseCustomDate(String strDate, String pattern) {
        if (StringUtils.isBlank(strDate)) {
            return null;
        }

        SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        try {
            formatter.setLenient(false);
            return formatter.parse(strDate);
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * 将Date时间转化为自定义格式字符串
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String format(Date date, String pattern) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        return dateFormat.format(date);
    }

    /**
     * 得到日期时间的"HH:mm:ss"这部分的字符串数据
     *
     * @param date
     * @return
     */
    public static String formatSpecialTime(Date date) {
        if (date == null) {
            return "";
        }
        String strTime = extTimeLocal.get().format(date);
        return strTime;
    }

    /**
     * 将Date时间格式化为"yyyy-MM-dd"标准日期
     *
     * @param time
     * @return
     */
    public static String formatDate(Date time) {
        if (time == null) {
            return "";
        }
        SimpleDateFormat dateFormat = dateLocal.get();
        return dateFormat.format(time);
    }

    /**
     * 转化日期为指定格式(yyyy-MM-dd HH:mm:ss)
     *
     * @param date
     * @return
     */
    public static String formatFullDate(Date date) {
        return formatCustomDate(date, PATTERN_TIME);
    }

    /**
     * 将Date时间格式化为"yyyy.MM"点分日期
     *
     * @param time
     * @return
     */
    public static String formatPointMonthDate(Date time) {
        if (time == null) {
            return "";
        }
        SimpleDateFormat dateFormat = monthPointLocal.get();
        return dateFormat.format(time);
    }

    /**
     * 将Date时间格式化为"yyyy.MM.dd"点分日期
     *
     * @param time
     * @return
     */
    public static String formatPointDate(Date time) {
        if (time == null) {
            return "";
        }
        SimpleDateFormat dateFormat = datePointLocal.get();
        return dateFormat.format(time);
    }

    /**
     * 将Date时间格式化为"yyyy-MM-dd HH:mm:ss.SSS"标准时间
     *
     * @param time
     * @return
     */
    public static String formatCustomTime(Date time) {
        if (time == null) {
            return "";
        }
        SimpleDateFormat dateFormat = customTimeLocal.get();
        return dateFormat.format(time);
    }

    /**
     * 将时间戳格式化为"yyyy-MM-dd HH:mm:ss.SSS"标准时间
     *
     * @param timestamp
     * @return
     */
    public static String formatMilliTime(Long timestamp) {
        return formatCustomTime(parseMilliTime(timestamp));
    }

    /**
     * 将Date时间格式化为"yyyy-MM-dd HH:mm:ss"标准时间
     *
     * @param time
     * @return
     */
    public static String formatTime(Date time) {
        if (time == null) {
            return "";
        }
        SimpleDateFormat dateFormat = timeLocal.get();
        return dateFormat.format(time);
    }

    /**
     * 将"HH:mm:ss"字符串转化为时间(yyyy-MM-dd HH:mm:ss)
     *
     * @param strTime
     * @return
     */
    public static Date parseSpecialTime(String strTime) {
        if (MixAllUtils.isEmpty(strTime)) {
            return null;
        }
        String strDate = formatDate(new Date());
        String value = strDate + " " + strTime;
        return parseTime(value);
    }

    /**
     * 转化标准时间
     *
     * @param day  标准日期 yyyy-MM-dd
     * @param time 标准时间 HH:mm:ss
     * @return
     */
    public static Date parseStandardDate(String day, String time) {
        if (MixAllUtils.isEmpty(time) || MixAllUtils.isEmpty(day)) {
            return null;
        }
        String value = day + " " + time;
        Date date = parseTime(value);
        return date;
    }

    /**
     * 判断字符串(HH:mm:ss)能否转化为Date
     *
     * @param strTime
     * @return
     */
    public static boolean canParseSpecialTime(String strTime) {
        if (MixAllUtils.isEmpty(strTime)) {
            return false;
        }
        String strDate = "2019-12-15";
        String value = strDate + " " + strTime;
        Date date = parseTime(value);
        boolean ok = date != null;
        return ok;
    }


    /**
     * 把Date转化为Calendar对象
     *
     * @param date
     * @return
     */
    public static Calendar toCalendar(final Date date) {
        final Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c;
    }

    /**
     * 比较日期(date1是否在date2之前) 格式要求：yyyy-MM-dd HH:mm:ss
     */
    public static boolean dateBefore(String date1, String date2) {
        Calendar c1 = toCalendar(parseTime(date1));
        Calendar c2 = toCalendar(parseTime(date2));
        return c1.before(c2);
    }

    /**
     * 比较date1对应的时间，是否比date2对应的时间小
     */
    public static boolean dateBefore(long date1, long date2) {
        boolean result = date1 < date2;
        return result;
    }

    /**
     * 比较date1对应的时间，是否比date2对应的时间小
     */
    public static boolean dateBefore(Date date1, Date date2) {
        long d1 = date1.getTime();
        long d2 = date2.getTime();
        boolean result = d1 < d2;
        return result;
    }

    /**
     * 比较日期(date1是否在date2之后) 格式要求：yyyy-MM-dd HH:mm:ss
     */
    public static boolean dateAfter(String date1, String date2) {
        Calendar c = toCalendar(parseTime(date1));
        Calendar c2 = toCalendar(parseTime(date2));
        return c.after(c2);
    }

    /**
     * 在date基础上 加/减指定second数
     *
     * @param second 加为正数,减为负数
     */
    public static Date getNextSecond(Date date, int second) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.SECOND, second);
        return cal.getTime();
    }

    /**
     * 获取指定日期往前第X天
     *
     * @param currentDate
     * @param x
     * @return
     */
    public static Date getPreDay(Date currentDate, int x) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);
        calendar.add(Calendar.DATE, -x);
        return calendar.getTime();
    }


    /**
     * 获取当前日期往前第X天
     *
     * @param x
     * @return
     */
    public static Date getPreDay(int x) {
        return getPreDay(new Date(), x);
    }

    /**
     * 获取指定时间往前第X小时
     *
     * @param currentDate
     * @param x
     * @return
     */
    public static Date getPreHour(Date currentDate, int x) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);
        calendar.add(Calendar.HOUR_OF_DAY, -x);
        return calendar.getTime();
    }

    /**
     * 获取指定时间往后第X小时
     *
     * @param currentDate
     * @param x
     * @return
     */
    public static Date getNextHour(Date currentDate, int x) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);
        calendar.add(Calendar.HOUR_OF_DAY, x);
        return calendar.getTime();
    }

    /**
     * 获取指定时间往后第X分钟
     *
     * @param currentDate
     * @param x
     * @return
     */
    public static Date getNextMinute(Date currentDate, int x) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);
        calendar.add(Calendar.MINUTE, x);
        return calendar.getTime();
    }

    /**
     * 获取指定时间往前第X分钟
     *
     * @param currentDate
     * @param x
     * @return
     */
    public static Date getPreMinute(Date currentDate, int x) {
        return getNextMinute(currentDate, -x);
    }

    /**
     * 获取指定日期，时间，小时，分钟第0秒
     *
     * @param date 指定时间
     * @return
     */
    public static Date getDateWithMaxSecond(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.SECOND, 59);
        c.set(Calendar.MILLISECOND, 999);
        return c.getTime();
    }

    /**
     * 获取指定时间往前第X小时
     *
     * @param currentDate
     * @param x
     * @return
     */
    public static String formatWithPreHour(Date currentDate, int x) {
        return formatFullDate(getPreHour(currentDate, x));
    }


    /**
     * 获取指定日期的第0时0分0秒
     *
     * @param date 指定时间
     * @return
     */
    public static Date getDateWithZeroHour(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    /**
     * 获取获取指定日期的第0时0分0秒
     *
     * @param date 指定时间
     * @return
     */
    public static String formatDateWithZeroHour(Date date) {
        return formatFullDate(getDateWithZeroHour(date));
    }

    /**
     * 获取当前时间对应小时的第0分0秒
     *
     * @param date 指定时间
     * @return
     */
    public static Date getDateWithZeroMinute(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    /**
     * 获取当前时间对应小时的第0分0秒
     *
     * @param date 指定时间
     * @return
     */
    public static String formatDateWithZeroMinute(Date date) {
        return formatFullDate(getDateWithZeroMinute(date));
    }

    /**
     * 获取当前时间对应分钟的第0秒
     *
     * @param date 指定时间
     * @return
     */
    public static Date getDateWithZeroSecond(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }


    /**
     * 获取当前时间对应分钟的第0秒
     *
     * @param date 指定时间
     * @return
     */
    public static Date getDateWithSecond(Date date, Integer second) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.SECOND, second);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    /**
     * 格式化当前时间对应分钟的第0秒
     *
     * @param date 指定时间
     * @return
     */
    public static String formatDateWithZeroSecond(Date date) {
        return formatFullDate(getDateWithZeroSecond(date));
    }

    /**
     * 获取当前时间对应小时的第59分59秒999毫秒
     *
     * @param date 指定时间
     * @return
     */
    public static Date getDateWithMaxMinute(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        c.set(Calendar.MILLISECOND, 999);
        return c.getTime();
    }

    /**
     * 获取当前时间对应小时的第59分59秒999毫秒
     *
     * @param date 指定时间
     * @return
     */
    public static String formatDateWithMaxMinute(Date date) {
        return formatFullDate(getDateWithMaxMinute(date));
    }

    /**
     * 获取当前时间对应小时的第59分59秒999毫秒
     *
     * @param date 指定时间
     * @param hour 小时数，注意是从0开始的，即当天最大是23小时， 24小时已经算是第二天的第0小时了
     * @return
     */
    public static Date getDateWithMaxMinute(Date date, int hour) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, hour);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        c.set(Calendar.MILLISECOND, 999);
        return c.getTime();
    }

    /**
     * 获取当前时间对应小时的第59分59秒999毫秒
     *
     * @param date 指定时间
     * @return
     */
    public static String formatDateWithMaxMinute(Date date, int hour) {
        return formatFullDate(getDateWithMaxMinute(date, hour));
    }

    /**
     * 获取指定日期的第X小时0分0秒0毫秒
     *
     * @param strDate 指定日期
     * @return
     */
    public static Date getDateWithCustomHour(String strDate, int hour) {
        Date date = parseCustomDate(strDate, PATTERN_DATE);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, hour);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    /**
     * 获取指定日期的第X小时0分0秒0毫秒
     *
     * @param strDate 指定日期
     * @return
     */
    public static String formatDateWithCustomHour(String strDate, int hour) {
        return formatFullDate(getDateWithCustomHour(strDate, hour));
    }

    /**
     * 判断统计时间的分钟是那个范围，例如提取09:43:32属于“40-50”分钟范围,而09:15:32属于“10-20”分钟范围
     *
     * @param statsDate
     * @return
     */
    public static int pickTenMinute(Date statsDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(statsDate);
        int minute = pickupMinute(calendar.getTime());
        int mod = minute % 10;
        int tenMinute = minute - mod;
        return tenMinute;
    }

    /**
     * 提取统计时间对应的小时数字，例如提取“2019-01-15 09:43:32”的“09”
     *
     * @param statsDate
     * @return
     */
    public static int pickupHour(Date statsDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(statsDate);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        return hour;
    }

    /**
     * 提取统计时间对应的分钟数字，例如提取“2019-01-15 09:43:32”的“43”
     *
     * @param statsDate
     * @return
     */
    public static int pickupMinute(Date statsDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(statsDate);
        int minute = calendar.get(Calendar.MINUTE);
        return minute;
    }

    /**
     * 计算minute对应的毫秒数
     *
     * @param minute
     * @return
     */
    public static Long buildDurationMillisecond(Long minute) {
        BigDecimal oneMinute = new BigDecimal(String.valueOf(ONE_MINUTE_DURATION));
        BigDecimal value = new BigDecimal(String.valueOf(minute)).multiply(oneMinute);
        return value.longValue();
    }

    /**
     * 计算date字段增加milliSecond毫秒之后的值
     *
     * @param millisecond
     * @param date
     * @return
     */
    public static Long addMilliSecond(Long millisecond, Date date) {
        BigDecimal oneMinute = new BigDecimal(String.valueOf(millisecond));
        BigDecimal value = new BigDecimal(String.valueOf(date.getTime())).add(oneMinute);
        return value.longValue();
    }

    /**
     * 构建间隔日期（字符串格式）
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<String> bulidSerialDate(Date startDate, Date endDate) {
        List<String> serialDays = new ArrayList<>();
        if (startDate == null || endDate == null) {
            return serialDays;
        }

        if (DateTimeUtils.formatDate(startDate).equalsIgnoreCase(DateTimeUtils.formatDate(endDate))) {
            serialDays.add(DateTimeUtils.formatDate(startDate));
            return serialDays;
        }

        int day = DateTimeUtils.diffDay(startDate, endDate);
        for (int i = 0; i <= day; i++) {
            String currentDay = DateTimeUtils.formatDate(DateTimeUtils.getPlusDay(startDate, i));
            if (!serialDays.contains(currentDay)) {
                serialDays.add(currentDay);
            }
        }
        return serialDays;
    }

    /**
     * 计算2个日期差异单位天数
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static int diffDay(Date startDate, Date endDate) {
        long t0 = startDate.getTime();
        long t1 = endDate.getTime();
        long diff = t1 - t0;
        int day = Double.valueOf(diff * 1D / ONE_DAY_SECOND).intValue();
        return day;
    }

    /**
     * 获取指定日期往后增加第X天
     *
     * @param currentDate
     * @param x
     * @return
     */
    public static Date getPlusDay(Date currentDate, int x) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);
        calendar.add(Calendar.DATE, x);
        return calendar.getTime();
    }


    /**
     * 判断当前hour表示的小时，是否为每天的“0点”
     *
     * @param hour
     * @return
     */
    public static Boolean isZeroHour(int hour) {
        return hour == ONE_DAY_ZERO_HOUR;
    }


    /**
     * 计算耗时操作，单位ms
     */
    public static long computeTime(final long beginTime) {
        return (System.currentTimeMillis() - beginTime);
    }

}
